package com.cong.cojcodesandbox.utils;

import cn.hutool.core.date.StopWatch;
import cn.hutool.core.util.StrUtil;
import com.cong.cojcodesandbox.mode.ExecuteMessage;
import io.netty.util.internal.StringUtil;
import org.apache.commons.lang3.StringUtils;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * 进程工具类
 *
 * @author 86188
 * @date 2023/09/05
 */
public class ProcessUtils {
    /**
     * 执行进程并获取信息
     *
     * @param runProcess
     * @param opName
     * @return {@link ExecuteMessage}
     */
    public static ExecuteMessage runProcessAndGetMessage(Process runProcess, String opName) throws IOException, InterruptedException {

        ExecuteMessage executeMessage = new ExecuteMessage();

            StopWatch stopWatch = new StopWatch();
            stopWatch.start();
            //等待程序执行 获取错误码
            int exitValue = runProcess.waitFor();
            executeMessage.setExitValue(exitValue);

            //正常退出
            if (exitValue == 0) {
                System.out.println(opName + "成功");
                //分批获取进程输出
                InputStreamReader inputStreamReader = new InputStreamReader(runProcess.getInputStream());
                BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
                //逐行读取
                String compileOutLine;
                List<String> outputStrList = new ArrayList<>();
                while ((compileOutLine = bufferedReader.readLine()) != null) {
                    outputStrList.add(compileOutLine);
                }
                inputStreamReader.close();

                executeMessage.setMessage(StringUtils.join(outputStrList,"\n"));
            } else {
                System.out.println(opName + "失败，错误码：" + exitValue);
                //分批获取进程输出
                InputStreamReader inputStreamReader = new InputStreamReader(runProcess.getInputStream());
                BufferedReader bufferedReader = new BufferedReader(inputStreamReader);


                //逐行读取
                String compileOutLine;

                List<String> outputStrList = new ArrayList<>();
                while ((compileOutLine = bufferedReader.readLine()) != null) {
                    outputStrList.add(compileOutLine);
                }
                inputStreamReader.close();

                executeMessage.setMessage(StringUtils.join(outputStrList,"\n"));


                //分批获取错误进程输出
                InputStreamReader errorInputStreamReader = new InputStreamReader(runProcess.getErrorStream());
                BufferedReader errorBufferedReader = new BufferedReader(errorInputStreamReader);

                //逐行读取
                String errorCompileOutLine;
                List<String> errorOutputStrList = new ArrayList<>();
                while ((errorCompileOutLine = errorBufferedReader.readLine()) != null) {
                    errorOutputStrList.add(errorCompileOutLine);
                }
                inputStreamReader.close();

                executeMessage.setErrorMessage(StringUtils.join(errorOutputStrList,"\n"));

                errorInputStreamReader.close();
                inputStreamReader.close();
            }
            runProcess.destroy();
            stopWatch.stop();
            executeMessage.setTime(stopWatch.getLastTaskTimeMillis());


        return executeMessage;
    }

    /**
     * 执行进程并获取信息
     *
     * @param runProcess
     * @param opName
     * @return {@link ExecuteMessage}
     */
    public static ExecuteMessage runInteractProcessAndGetMessage(Process runProcess, String opName,String args) {
        ExecuteMessage executeMessage = new ExecuteMessage();

        try {
            //向控制台输入程序
            OutputStream outputstream = runProcess.getOutputStream();

            OutputStreamWriter outputstreamWriter = new OutputStreamWriter(outputstream);
            String[] s = args.split(" ");
            args = StrUtil.join("\n", s) + "\n";
            outputstreamWriter.write(args);
            //相当于按了回车，执行输入的发送
            outputstreamWriter.flush();


            //分批获取进程输出
            InputStream inputStream = runProcess.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            //逐行读取
            String compileOutLine;
            StringBuilder compileOutputstringBuilder = new StringBuilder();
            while ((compileOutLine = bufferedReader.readLine()) != null) {
                compileOutputstringBuilder.append(compileOutLine);
            }
            //释放资源
            inputStream.close();
            outputstream.close();
            inputStreamReader.close();
            outputstreamWriter.close();
            executeMessage.setMessage(compileOutputstringBuilder.toString());

            runProcess.destroy();

        } catch (IOException  e) {
            throw new RuntimeException(e);
        }

        return executeMessage;
    }
}
